#ifndef TIEC_COMPONENT_H
#define TIEC_COMPONENT_H

#include "data.h"
#include "foundation.h"
#include "tree.h"
#include "tree_path.h"
#include "android/android_output.h"
#include "cxx/cxx_output.h"

/// Component名称宏
/// @param cls Component类名
#define COMPONENT_NAME(cls) kComponent##cls

/// Component getType函数快捷定义
/// @param cls Component类名
#define DEF_COMPONENT_TYPE(cls) String cls::getType() { \
  return COMPONENT_NAME(cls); \
}

/// Component 组件名变量定义
/// @param cls Component类名
#define DEF_COMPONENT_NAME(cls) static constexpr const char* COMPONENT_NAME(cls) = #cls;

/// Component instance工厂函数声明
/// @param cls Component类名
#define DECL_COMPONENT_FACTORY(cls) static PTR<cls> instance(const PTR<Context>& context);

/// Component instance工厂函数定义，用于Component无参构造函数的情况
/// @param cls Component类名
#define DEF_COMPONENT_FACTORY(cls) PTR<cls> cls::instance(const PTR<Context>& context) { \
  PTR<cls> instance = context->getComponent<cls>(); \
  if (instance == nullptr) { \
    instance = MAKE_PTR<cls>(); \
    context->addComponent(instance); \
  } \
  return instance; \
}

/// Component instance工厂函数定义，用于Component构造参数为编译器上下文Context的情况
/// @param cls Component类名
#define DEF_COMPONENT_FACTORY_WITH_CONTEXT(cls) PTR<cls> cls::instance(const PTR<Context>& context) { \
  PTR<cls> instance = context->getComponent<cls>(); \
  if (instance == nullptr) { \
    instance = MAKE_PTR<cls>(context); \
    context->addComponent(instance); \
  } \
  return instance; \
}

/// 注解方法体声明，包含对AnnotationProcessor所有virtual方法的override以及参数列表声明
/// @param class_name 注解处理器类名
#define DECL_ANNOTATION_BODY(class_name) \
  public: \
    explicit class_name(const PTR<Context>& context); \
    TaskKind getTaskKind() override; \
    Modifiers getLevelModifiers() override; \
    List<PTR<AnnotationParameter>>& getParameters() override; \
    ProcessResult processTree(const PTR<AnnotatedTree>& tree, \
      const PTR<AnnotationArgumentMap>& arguments, const PTR<Context>& context) override; \
  private: \
    List<PTR<AnnotationParameter>> parameters_;

/// 默认注解类声明，包含整个注解处理器类的声明及成员声明
/// @param class_name 注解处理器类名
#define DECL_ANNOTATION_CLASS(class_name) \
  class class_name : public AnnotationProcessor { \
  DECL_ANNOTATION_BODY(class_name) \
  };

/// 注解处理器方法体(getTaskKind、getLevelModifiers、getParameters)定义
/// @param class_name 注解处理器类名
/// @param task_kind 注解处理器要执行的任务阶段
/// @param levels 注解处理器支持标注的成员级别（类、方法、变量）
#define DEF_ANNOTATION_BODY(class_name, task_kind, levels) \
  TaskKind class_name::getTaskKind() { \
    return task_kind; \
  } \
  Modifiers class_name::getLevelModifiers() { \
    return Modifiers{levels}; \
  } \
  List<PTR<AnnotationParameter>>& class_name::getParameters() { \
    return parameters_; \
  }

/// 注解处理器构造函数定义宏，用于快捷定义构造函数
/// @param class_name 注解处理器类名
#define DEF_ANNOTATION_INIT(class_name) \
  class_name::class_name(const PTR<Context>& context): AnnotationProcessor(context)

/// 注解处理器 processTree 函数定义宏，用于快捷定义 processTree 函数
/// @param class_name 注解处理器类名
#define DEF_ANNOTATION_PROCESS(class_name) \
  ProcessResult class_name::processTree(const PTR<AnnotatedTree>& tree, \
    const PTR<AnnotationArgumentMap>& arguments, const PTR<Context>& context)

namespace NS_TIEC {
  /// 编译器组件
  class Component {
  public:
    /// 组件类型
    /// \return 组件的名称(type)
    virtual String getType() = 0;
  };

  /// 组件的Key模板
  template<typename T>
  size_t keyOfComponent() {
    return typeid(T).hash_code();
  };

  /// 编译器组件上下文
  class Context {
  public:
    ~Context();

    /// 获取上下文中指定编译器组件
    /// \tparam T 组件类型
    /// \return 对应的编译器组件，如果找不到则返回空指针
    template<class T>
    PTR<T> getComponent() {
      auto key = keyOfComponent<T>();
      if (components_.contains(key)) {
        return std::static_pointer_cast<T>(components_[key]);
      }
      return nullptr;
    }

    /// 获取上下文中指定编译器组件，如果没有则执行创建
    /// \tparam T 组件类型
    /// \param supplier 创建组件的函数
    /// \return 对应的编译器组件，如果找不到则返回空指针
    template<class T>
    PTR<T> getComponentOrCreate(FUNCTION<PTR<T>()> supplier) {
      auto key = keyOfComponent<T>();
      if (!components_.contains(key)) {
        PTR<T> instance = supplier();
        components_.put(key, instance);
      }
      return std::static_pointer_cast<T>(components_[key]);
    }

    /// 获取上下文中指定编译器组件，如果没有则自动创建为智能指针
    /// \tparam T 组件类型
    /// \return 对应的编译器组件
    template<class T>
    PTR<T> getComponentOrCreateDefault() {
      auto key = keyOfComponent<T>();
      if (!components_.contains(key)) {
        PTR<T> instance = MAKE_PTR<T>();
        components_.put(key, instance);
      }
      return std::static_pointer_cast<T>(components_[key]);
    }

    /// 在上下文中注册一个编译器组件
    /// \tparam T 组件类型
    /// \param component 编译器组件
    template<class T>
    void addComponent(PTR<T>& component) {
      auto key = keyOfComponent<T>();
      components_.put(key, component);
    }

    /// 在上下文中注册一个编译器组件
    /// \tparam Base 组件基类
    /// \tparam Impl 组件实现类
    /// \param component 编译器组件
    template<class Base, class Impl>
    void addComponent(PTR<Impl>& component) {
      auto key = keyOfComponent<Base>();
      components_.put(key, component);
    }

    /// 判断在上下文中是否存在指定组件
    /// \tparam T 组件类型
    /// \return 如果存在则返回true
    template<class T>
    bool hasComponent() {
      auto key = keyOfComponent<T>();
      return components_.contains(key);
    }

  private:
    HashMap<size_t, PTR<Component>> components_;
  };

  /// 编译器支持的输出平台枚举
  enum struct TargetPlatform {
    kUndefined = 0,
    kAndroid,
    kHarmony,
    kLinux,
    kWindows,
    kIOS,
    kApple,
    kHtml,
  };

  /// 将TargetPlatform转为String输出
  /// @param platform TargetPlatform
  String platformToString(const TargetPlatform& platform);

  /// 检查局部变量遮蔽
  static String kLintShadowedVar = "var.shadowed";
  /// 检查遍历循环解构赋值
  static String kLintForEachDestruct = "for-each.destruct";
  /// 检查类型自动强转
  static String kLintAutoTypeCast = "auto.type-cast";
  /// 检查对象访问静态成员
  static String kLintObjectAccessStatic = "object.access-static";
  /// 检查方法返回值
  static String kLintMethodReturn = "method.return";
  /// 编译选项
  class Options : public Component {
  public:
    static Options kDefault;

    /// 默认包名
    String package_name;
    /// 输出路径
    String output_dir;
    /// 行号表输出路径
    String line_map_path;
    /// 是否debug模式
    bool debug{true};
    /// 是否进行硬输出，所有用到的文件都拷贝到输出目录，而不是使用地址引用
    bool hard_mode{false};
    /// 是否使用友好名称输出，而不是随即名称(rn_xx)
    bool friendly_name {false};
    /// 是否支持树形源文件组合
    bool enable_tree_source{false};
    /// 是否支持嵌入式代码
    bool enable_code{true};
    /// 是否支持顶级语句，即在类之外编写语句
    bool enable_top_statements{true};
    /// 泛型是否使用生成新类的方式进行实现
    bool template_type_newclass{false};
    /// 是否开启流程检查
    bool enable_flow_check{false};
    /// 是否为IDE模式
    bool ide_mode{false};
    /// 优化级别
    /// 0:不优化
    /// 1:基础常量传播、常量折叠、死代码消除
    /// 2:1的基础上增加方法调用静态内联
    /// 3:2的基础上增加方法动态内联(直接解释运行方法生成最终常量结果)、循环变量外提、循环展开
    int optimize_level {1};
    /// 要屏蔽的lint选项
    Set<String> lint_disable {};
    /// 日志输出级别
    LogLevel log_level {LogLevel::kLevelDebug};
    /// 输出的目标平台
    TargetPlatform platform {TargetPlatform::kUndefined};

#ifdef TIEC_DEBUG
    String resolvable_class {};
#endif

    /// 判断是否屏蔽了指定的Lint选项
    /// @param name Lint配置名称
    const bool isDisableLint(const String& name) const;

    String getType() override;
    DECL_COMPONENT_FACTORY(Options)
  };

  /// Name对象池组件
  class NameTable : public Component {
  public:
    PTR<Name> error;
    PTR<Name> tiecode_basic;
    PTR<Name> null_literal;
    PTR<Name> this_object;
    PTR<Name> super_object;
    PTR<Name> code_ref_this;
    PTR<Name> code_ref_cls;
    PTR<Name> code_ref_ncls;
    PTR<Name> code_ref_mem;
    PTR<Name> code_ref_sys;
    PTR<Name> code_ref_expr;
    PTR<Name> alias_obj;
    PTR<Name> type_string;
    PTR<Name> type_int;
    PTR<Name> type_long;
    PTR<Name> type_float;
    PTR<Name> type_double;
    PTR<Name> type_bool;
    PTR<Name> type_char;
    PTR<Name> type_byte;
    PTR<Name> type_variant;
    PTR<Name> const_file;
    PTR<Name> const_color;
    PTR<Name> op_array_access;
    PTR<Name> op_array_assign;
    PTR<Name> op_assign;
    PTR<Name> op_question;
    PTR<Name> op_plus;
    PTR<Name> op_minus;
    PTR<Name> op_mul;
    PTR<Name> op_div;
    PTR<Name> op_xor;
    PTR<Name> op_mod;
    PTR<Name> op_equals;
    PTR<Name> op_not_equals;
    PTR<Name> op_less;
    PTR<Name> op_greater;
    PTR<Name> op_less_equals;
    PTR<Name> op_greater_equals;
    PTR<Name> arr_length;
    PTR<Name> default_annotation_param;
    PTR<Name> to_string;
    PTR<Name> type_iterator_;
    PTR<Name> type_map_entry_;
    PTR<Name> get_iterator_;
    PTR<Name> iterator_has_next_;
    PTR<Name> iterator_next_;
    PTR<Name> map_entry_key_;
    PTR<Name> map_entry_value_;
    PTR<Name> async_executor_;
    PTR<Name> executor_create_;
    PTR<Name> executor_submit_global_;
    PTR<Name> executor_submit_global_end_;
    PTR<Name> executor_submit_;
    PTR<Name> executor_submit_end_;
    PTR<Name> executor_main_;
    PTR<Name> executor_main_end_;
    // 系统注解处理器名称
    PTR<Name> proc_static;
    PTR<Name> proc_private;
    PTR<Name> proc_virtual_method;
    PTR<Name> proc_virtual_event;
    PTR<Name> proc_force_output;
    PTR<Name> proc_forbid_new;
    PTR<Name> proc_forbid_output;
    PTR<Name> proc_global_class;
    PTR<Name> proc_platform_code;
    PTR<Name> proc_debug;
    PTR<Name> proc_operator_overload;
    PTR<Name> proc_auto_subscribe;
    PTR<Name> proc_forbid_pointer;
    PTR<Name> proc_async_method;
    PTR<Name> proc_deprecated;
    PTR<Name> proc_default_super_class;
    PTR<Name> proc_const_type;
    PTR<Name> proc_required_type;
    PTR<Name> proc_value_output_rule;
    PTR<Name> proc_file_pattern;
    PTR<Name> proc_output_name;
    PTR<Name> proc_alias_class;
    PTR<Name> proc_external_super_class;
    PTR<Name> proc_event_property;
    PTR<Name> async_method_unique_thread; // 异步方法的独立模式参数
    /// 安卓平台注解处理器名称
    PTR<Name> proc_manifest_app_property;
    PTR<Name> proc_manifest_component_property;
    PTR<Name> proc_manifest_component_child;
    PTR<Name> proc_manifest_file_associate;
    PTR<Name> proc_manifest_uri_associate;
    PTR<Name> proc_layout_config;
    PTR<Name> proc_resource_drawable;
    PTR<Name> proc_resource_anim;
    PTR<Name> proc_resource_layout;
    PTR<Name> proc_resource_xml;
    PTR<Name> proc_theme_parent_config;
    PTR<Name> proc_theme_property;
    PTR<Name> proc_theme_primary;
    PTR<Name> proc_theme_primary_dark;
    PTR<Name> proc_theme_status_bar;
    PTR<Name> proc_theme_nav_bar;
    PTR<Name> proc_theme_window_background;
    PTR<Name> proc_theme_view_foreground;
    PTR<Name> proc_theme_view_background;
    PTR<Name> proc_theme_view_accent;
    PTR<Name> proc_theme_view_control;
    PTR<Name> proc_theme_button_normal;
    PTR<Name> proc_theme_text_primary;
    /// Cxx平台注解处理器名称
    PTR<Name> proc_external_cxx_source;
    PTR<Name> proc_external_cxx_lib;
    PTR<Name> proc_include_header;
    PTR<Name> proc_cxx_prefix_code;
    PTR<Name> proc_cxx_suffix_code;
    /// 嵌入式代码Tag
    PTR<Name> code_tag_header;

    NameTable();

    /// 通过文本取得一个唯一地址的Name指针
    /// @param str 文本内容
    /// @return 只要文本内容值相同，会始终指向同一个Name
    PTR<Name> getName(const String& str);

    /// 判断指定Name是否为基本类型名称
    /// @param name 名称
    bool isBasicTypeName(const PTR<Name>& name) const;

    /// 根据token获取运算符名称
    /// @param token token
    PTR<Name> getOperatorName(TiecodeToken token) const;

    String getType() override;
    DECL_COMPONENT_FACTORY(NameTable)
  private:
    HashMap<String, PTR<Name>> name_map_;
  };

  /// 诊断信息处理器接口
  class DiagnosticHandler {
  public:
    /// 输出诊断信息
    /// \param diagnostic 诊断信息详情
    virtual void report(Diagnostic& diagnostic) = 0;
  };

  class StdOutDiagnosticHandler : public DiagnosticHandler {
    public:
    virtual void report(Diagnostic& diagnostic) override;
  };

  /// 消息收集器
  class Messages : public Component {
  public:
    Messages();

    /// 收集提示信息级别的日志
    /// \param message 信息文本内容
    virtual void info(const String& message);

    /// 收集警告级别的日志
    /// \param message 信息文本内容
    virtual void warning(const String& message);

    /// 收集错误级别的日志
    /// \param message 信息文本内容
    virtual void error(const String& message);

    /// 收集致命错误级别的日志
    /// \param message 信息文本内容
    virtual void fatalError(const String& message);

    /// 收集诊断信息
    /// \param diagnostic 诊断信息
    virtual void diagnostic(Diagnostic& diagnostic);

    /// 当前是否有致命错误，如果有，后续流程将停止进行
    virtual bool hasFatalError();

    /// 获取收集到的错误数量
    virtual UInt32 errorCount();

    /// 获取收集到的警告数量
    virtual UInt32 warningCount();

    /// 设置诊断信息输出器
    /// @param handler 诊断信息输出器实现
    void setDiagnosticHandler(const PTR<DiagnosticHandler>& handler);

    String getType() override;
    DECL_COMPONENT_FACTORY(Messages)
  private:
    UInt32 error_count_{0};
    UInt32 warning_count_{0};
    bool fatal_mark_{false};
    PTR<DiagnosticHandler> diagnostic_handler_;
    LogLevel log_level_ {LogLevel::kLevelDebug};
  };

  /// 源文件管理
  class SourceManager : public Component {
  public:
    /// 添加一个源文件
    /// @param source 源文件
    void addSource(PTR<Source>& source);

    /// 添加多个源文件
    /// @param sources 源文件列表
    void addSourceList(const List<PTR<Source>>& sources);

    /// 通过Uri获取源文件
    /// @param uri 源文件的Uri
    PTR<Source> getSource(const Uri& uri);

    /// 获取某个子树源文件的根节点源文件
    /// @param source 子树源文件
    /// @return 根节点源文件
    PTR<Source> getSourceRoot(const PTR<Source>& source) const;

    /// 获取源文件集合
    /// @return 当前编译环境下所有源文件
    Set<PTR<Source>> getSourceSet() const;

    /// 遍历所有源文件
    /// @param consumer 源文件遍历函数
    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, const PTR<Source>&>>>
    void forEachSource(Func&& consumer) const {
      sources_.forEach(std::forward<Func>(consumer));
    }

    /// 根据Source获取其ID
    /// @param source Source实例
    /// @return
    Int64 getIdForSource(const PTR<Source>& source);

    /// 根据ID获取对应的Source
    /// @param id Source的Id
    /// @return
    PTR<Source> getSourceById(const Int64 id) const;

    /// 根据ID获取对应的Source Uri
    /// @param id Source的Id
    /// @return
    Uri getSourceUriById(const Int64 id) const;

    /// 将源文件ID映射表拷贝至行号映射表文件
    void copyToSourceMapping(SourceMapping& mapping);

    String getType() override;
    DECL_COMPONENT_FACTORY(SourceManager)
  private:
    Set<PTR<Source>, SourcePtrHash, SourcePtrEqual> sources_;
    // 这里存每个子树源文件指向编译单元根节点源文件的索引，便于直接索引到根节点，重建整个语法树
    HashMap<PTR<Source>, PTR<Source>, SourcePtrHash, SourcePtrEqual> source_root_map_;
    // 存Source和id的映射
    HashMap<PTR<Source>, Int64, SourcePtrHash, SourcePtrEqual> source_id_map_;
    HashMap<Int64, PTR<Source>> id_source_map_;
    Int64 source_id_used_ {0};

    void registrySourceRootMapping(const PTR<Source>& source, const PTR<Source>& root);
  };

  /// 编译单元合并器，源文件可以为树形结构组合，当启用树形源文件时，可以将多个树形源文件中所有编译单元组合到根节点形成完整的编译单元，
  /// 组合的编译单元必须有层级规范，顶层必须为类定义、下一级必须是方法、事件，再往下一级只能是语句，语句可以无限层级嵌套
  class CompilationUnitMerger : public Component {
  public:
    explicit CompilationUnitMerger(const PTR<Context>& context);

    /// 将编译单元中顶级语句合成到特定的方法或事件（比如安卓平台合成到“事件 窗口:创建完毕()”）
    /// @param root 根节点编译单元
    virtual void synthesizeTopLevelStatements(const PTR<CompilationUnitTree>& root) const;

    /// 将子编译单元合并到父编译单元
    /// @param parent 父节点
    /// @param child 子节点
    void merge(const PTR<CompilationUnitTree>& parent, const PTR<CompilationUnitTree>& child) const;

    String getType() override;
    DECL_COMPONENT_FACTORY(CompilationUnitMerger)
  protected:
    WPTR<Messages> messages_;
    WPTR<SourceManager> sources_;

    void mergeMemberToTopLevel(const PTR<CompilationUnitTree>& parent, const PTR<CompilationUnitTree>& child) const;
    void mergeStatementsToMember(const PTR<CompilationUnitTree>& parent, const PTR<CompilationUnitTree>& child) const;
    void mergeStatementsToStatement(const PTR<CompilationUnitTree>& parent, const PTR<CompilationUnitTree>& child) const;
    static const char* getUnitKindDescription(const CompilationUnitKind kind);
  };

  using ClassWithUnit = PAIR<PTR<CompilationUnitTree>, PTR<ClassTree>>;
  // 语法树表
  class TreeTable : public Component {
  public:
    /// @brief 插入或更新某个源文件的语法树，由于源文件是树形结构，所以一般每次更新都会调用多次
    /// @param source 源文件
    /// @param tree 根节点
    void addOrUpdateTree(const PTR<Source>& source, const PTR<CompilationUnitTree>& tree);

    /// @brief 移除某个源文件的语法树，由于源文件是树形结构，所以一般每次更新都会调用多次
    /// @param source 源文件
    /// @param source_id 源文件ID
    void removeTreesBySource(const PTR<Source>& source, Int64 source_id);

    /// 获取源文件对应的语法树
    /// @param source 源文件
    PTR<CompilationUnitTree> getTree(const PTR<Source>& source) const;

    /// @brief 遍历TreeTable（只包含源代码的编译单元，不包含模板实现类）
    /// @param consumer 遍历函数
    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, const PTR<Source>&, const PTR<CompilationUnitTree>&>>>
    void forEach(Func&& consumer) {
      source_uint_map_.forEach(std::forward<Func>(consumer));
    }

    /// @brief 遍历TreeTable，遇到return true时停止遍历
    /// @param consumer 遍历函数
    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, bool, const PTR<Source>&, const PTR<CompilationUnitTree>&>>>
    void forEachUntil(Func&& consumer) {
      source_uint_map_.forEachUntil(std::move(consumer));
    }

    /// 存放一组类名到类的键值对
    /// @param full_name 完整类名
    /// @param root_tree 类所处编译单元
    /// @param class_tree 类定义
    void storeClassWithUnit(const PTR<Name>& full_name, const PTR<CompilationUnitTree>& root_tree, const PTR<ClassTree>& class_tree);

    /// 通过完整类名取得其所定义的ClassTree和所在编译单元
    /// @param full_name 完整类名
    ClassWithUnit getClassWithUnit(const PTR<Name>& full_name) const;

    /// 遍历所有类（包含模板实现类）
    /// @param consumer 遍历函数
    template<typename Func, typename = std::enable_if_t<is_lambda_with_signature<Func, void, const PTR<Name>&, const ClassWithUnit&>>>
    void forEachClassWithUnit(Func&& consumer) {
      name_class_map_.forEach(std::forward<Func>(consumer));
    }

    /// 存储方法参数默认值
    /// @param param 参数Symbol
    /// @param def_value 默认值表达式
    void addParamDefaultValue(const PTR<VarSymbol>& param, const PTR<ExpressionTree>& def_value);

    /// 获取指定参数的默认值表达式
    /// @param param 参数Symbol
    /// @return 参数的默认值表达式
    PTR<ExpressionTree> getParamDefaultValue(const PTR<VarSymbol>& param) const;

    String getType() override;
    DECL_COMPONENT_FACTORY(TreeTable)
  private:
    // 这里存的 CompilationUnitTree 是经过多个子树源文件合并之后的Tree，不存独立的Tree，便于重建整个编译单元语法树
    HashMap<PTR<Source>, PTR<CompilationUnitTree>, SourcePtrHash, SourcePtrEqual> source_uint_map_;
    // 存完整类名到 键值对<编译单元,类>
    HashMap<PTR<Name>, ClassWithUnit, NamePtrHash, NamePtrEqual> name_class_map_;
    /// 方法参数默认值
    HashMap<PTR<VarSymbol>, PTR<ExpressionTree>> param_def_values_;
  };

  // 符号表
  class SymbolTable : public Component {
  public:
    // 全局的基础父类
    PTR<ClassSymbol> global_super_class;
    // 基础类型Type
    PTR<ClassType> type_int;
    PTR<ClassType> type_long;
    PTR<ClassType> type_char;
    PTR<ClassType> type_bool;
    PTR<ClassType> type_byte;
    PTR<ClassType> type_float;
    PTR<ClassType> type_double;
    PTR<ClassType> type_string;
    PTR<VariantType> type_variant;
    PTR<VoidType> type_void;
    PTR<NullType> type_null;
    // 遍历循环需要的类型
    PTR<TemplateType> type_iterator_;
    PTR<TemplateType> type_map_entry_;
    PTR<MethodSymbol> iterator_has_next_;
    PTR<MethodSymbol> iterator_next_;
    PTR<MethodSymbol> map_entry_key_;
    PTR<MethodSymbol> map_entry_value_;
    // 异步方法需要的类型
    PTR<ClassSymbol> async_executor_;
    PTR<MethodSymbol> executor_create_;
    PTR<MethodSymbol> executor_submit_global_;
    PTR<MethodSymbol> executor_submit_global_end_;
    PTR<MethodSymbol> executor_submit_;
    PTR<MethodSymbol> executor_submit_end_;
    PTR<MethodSymbol> executor_main_;
    PTR<MethodSymbol> executor_main_end_;

    explicit SymbolTable(const PTR<Context>& context);

    /// @brief 添加一个包名Symbol
    /// @param pkg 包名Symbol定义
    void definePackage(const PTR<PackageSymbol>& pkg);

    /// @brief 添加一个类Symbol，如果已有重名的，则添加到List
    /// @param klass 类Symbol定义
    void defineClass(const PTR<ClassSymbol>& klass);

    /// @brief 移除某个源文件定义的ClassSymbol
    /// @param source 源文件
    /// @param source_id 源文件ID
    void removeClassBySource(const PTR<Source>& source, Int64 source_id);

    /// @brief 实现一个模板类
    /// @param template_name 模板类完整类名
    /// @param key 模板实现参数的key
    /// @param impl_symbol 具体实现的ClassSymbol
    void implTemplateClass(const PTR<Name>& template_name, const String& key, const PTR<ClassSymbol>& impl_symbol);

    /// 获取模板类型实现的Class
    /// @param template_name 模板类型完整类名
    /// @param key 模板实现参数的key
    /// @return 具体实现的ClassSymbol
    PTR<ClassSymbol> getTemplateImplClass(const PTR<Name>& template_name, const String& key) const;

    /// 检查class是否为基本类型定义类，如果是则初始化基本类型
    /// @param klass 要处理的ClassSymbol
    void checkBasicTypeClass(const PTR<ClassSymbol>& klass);

    /// 根据基本类型标识符名称获取基本类型Type定义
    /// @param name 基本类型名称
    PTR<ClassType> getBasicTypeByName(const PTR<Name>& name) const;

    /// 检查指定类型是否为基本类型
    /// @param type 类型
    bool isBasicType(const PTR<Type>& type) const;

    /// 检查class是否为遍历循环需要的类型，如果是则初始化
    /// @param klass 要处理的ClassSymbol
    void checkIteratorTypeClass(const PTR<ClassSymbol>& klass);

    /// 根据包名获取PackageSymbol
    /// @param name 包名
    PTR<PackageSymbol> getPackage(const PTR<Name>& name) const;

    /// 根据包名和类名获取 ClassSymbol
    /// @param pkg_name 包名
    /// @param name 类名
    PTR<ClassSymbol> getClass(const PTR<Name>& pkg_name, const PTR<Name>& name) const;

    /// 根据完整类名获取 ClassSymbol
    /// @param full_name 包名
    PTR<ClassSymbol> getUniqueClass(const PTR<Name>& full_name) const;

    /// 根据类名获取名称为指定文本的 ClassSymbol
    /// @param name 类名
    PTR<ClassSymbol> getFirstClass(const PTR<Name>& name) const;

    /// 根据类名获取所有相同名称的ClassSymbol
    /// @param name 类名
    List<PTR<ClassSymbol>> getClasses(const PTR<Name>& name) const;

    /// 移除某个源文件定义的所有Symbol
    /// @param source 源文件
    void removeSymbolWithSource(const PTR<Source>& source);

    /// 遍历当前环境中每一个ClassSymbol
    /// @param consumer 遍历函数
    void forEachClass(VOID_FUNCTION(const PTR<ClassSymbol>& symbol) consumer);

    /// 判断类型是否为基本数值类型（字节/整数/长整数/小数/单精度小数）
    /// @param type 要判断的类型
    inline bool isNumericType(const PTR<Type>& type) {
      return (type == type_int || type == type_long || type == type_float || type == type_double || type == type_byte);
    }

    /// 获取数值类型的优先级
    /// @param type 数值类型
    /// @return 
    inline int getNumericTypePrecedence(const PTR<Type>& type) {
      if (type == this->type_double) {
        return 5;
      }
      if (type == this->type_float) {
        return 4;
      }
      if (type == this->type_long) {
        return 3;
      }
      if (type == this->type_int) {
        return 2;
      }
      if (type == this->type_byte) {
        return 1;
      }
      return 0;
    }

    /// 查找全局类成员
    /// @param name 成员名称
    /// @param filter 过滤函数
    template<typename Func, typename = std::enable_if_t<is_lambda_or_func<Func, bool, const PTR<Symbol>&>>>
    PTR<Symbol> getGlobalSymbol(const PTR<Name>& name, Func&& filter) const {
      for (const PAIR<const PTR<Name>, List<PTR<ClassSymbol>>>& pair : class_map_) {
        for (const PTR<ClassSymbol>& class_sym : pair.second) {
          if (!class_sym->modifiers.has(Modifiers::kGlobalClass)) {
            continue;
          }
          const PTR<Symbol> member = class_sym->getMember(name, filter, false);
          if (member != nullptr) {
            return member;
          }
        }
      }
      return nullptr;
    }

    String getType() override;
    DECL_COMPONENT_FACTORY(SymbolTable)
  private:
    HashMap<PTR<Name>, PTR<PackageSymbol>, NamePtrHash, NamePtrEqual> package_map_;
    HashMap<PTR<Name>, List<PTR<ClassSymbol>>, NamePtrHash, NamePtrEqual> class_map_;
    // 存每个模板类的实现（实现类型key to ClassSymbol），为什么不存 PTR<ClassSymbol>，因为ClassSymbol可能在IDE服务时实时更新造成地址改变，但完整类名一定是不变的
    // 暂时先留着，虽然现在不用
    HashMap<PTR<Name>, HashMap<String, PTR<ClassSymbol>>, NamePtrHash, NamePtrEqual> template_impl_map_;
    PTR<SourceManager> sources_;
    PTR<NameTable> names_;
  };

  /// 编译器通用规范的名称重整器，用于为Symbol生成编译输出名称，不使用原有中文名
  class NameMangler : public Component {
  public:
    explicit NameMangler(const PTR<Context>& context);

    /// 为指定Symbol生成输出名
    /// @param symbol 当前要处理的Symbol
    /// @return Symbol编译输出时所需要使用的名称
    String mangle(const PTR<Symbol>& symbol);

    /// 随机生成一个名称，用作编译器生成的临时变量名称
    String randName();

    /// 判断用户使用的输出名是否合法
    /// @param name 用户指定的输出名
    bool nameIsExpected(const String& name);

    /// 加载之前生成过的名称映射表进行复用，保证本次编译输出名称与上一次一致
    /// @param file 名称映射文件
    void loadMapping(const File& file);

    /// 将输出名映射保存到指定文件，便于下次复用
    /// @param file
    void generateMapping(const File& file);

    String getType() override;
    DECL_COMPONENT_FACTORY(NameMangler)
  private:
    UInt64 name_index_ {1};
    bool friendly_name_{false};
    TargetPlatform platform_;
    WPTR<NameTable> name_tab_;

    String getOperatorFriendlyName(const PTR<Name>& name) const;
  };

  /// 注解参数类型枚举
  enum struct ParameterType {
    /// 空类型
    kNull = 0,
    /// 文本类型
    kString,
    /// 整数类型
    kInteger,
    /// 布尔值
    kBoolean,
    /// 类型名称引用
    kType,
    /// 符号引用
    kSymbol,
    /// 属性表 {属性A=值A, 属性B=值B ... }
    kProperties
  };

  /// 将 ParameterType 转换为String描述
  /// @param type ParameterType
  String parameterTypeToString(const ParameterType& type);

  /// 注解形式参数描述
  struct AnnotationParameter {
    /// 参数类型
    ParameterType type {ParameterType::kString};
    /// 参数名称
    PTR<Name> name;
    /// 参数描述信息
    String description;
    /// 是否为可选参数（非必须）
    bool is_optional {false};

    AnnotationParameter(ParameterType type, const PTR<Name>& name,
      String&& description, bool is_optional = false);
    AnnotationParameter(ParameterType type, const PTR<Name>& name,
      const String& description, bool is_optional = false);
  };

  /// 常量属性表
  class ConstPropertyList {
  public:
    /// 判断属性表中是否有某个属性
    /// @param name 属性名
    const bool hasProperty(const PTR<Name>& name) const;

    /// 获取属性值
    /// @param name 属性名
    /// @return 对应的属性值
    ConstValue getProperty(const PTR<Name>& name) const;

    /// 设置属性值
    /// @param name 属性名
    /// @param value 属性值
    void addProperty(const PTR<Name>& name, ConstValue&& value);

    /// 设置属性值
    /// @param name 属性名
    /// @param value 属性值
    void addProperty(const PTR<Name>& name, const ConstValue& value);
  private:
    std::vector<PAIR<const PTR<Name>, ConstValue>> properties_;
  };

  /// 注解实际调用参数
  struct AnnotationArgument {
    /// 注解参数类型
    ParameterType type {ParameterType::kNull};
    /// 常量值(对应 ParameterType::kString ParameterType::kInteger ParameterType::kBoolean)
    ConstValue const_value {ConstValue::kNull};
    /// 引用类型(对应 ParameterType::kType)
    PTR<ClassType> class_type;
    /// 引用类成员符号(对应 ParameterType::kSymbol)
    PTR<Symbol> member_symbol;
    /// 属性表(对应 ParameterType::kProperties)
    PTR<ConstPropertyList> properties;
    /// 在语法树中的表达式
    PTR<ExpressionTree> tree;
    /// 原始位置信息
    Origin origin;

    explicit AnnotationArgument(ConstValue&& const_value, const Origin& origin);
    explicit AnnotationArgument(const ConstValue& const_value, const Origin& origin);
    explicit AnnotationArgument(const PTR<ClassType>& class_type, const Origin& origin);
    explicit AnnotationArgument(const PTR<Symbol>& member_sym, const Origin& origin);
    explicit AnnotationArgument(const PTR<ConstPropertyList>& properties, const Origin& origin);
  };

  /// 多个注解参数包装
  struct AnnotationArgumentMap {
    // 参数表
    HashMap<PTR<Name>, PTR<AnnotationArgument>> arguments;
    // 注解的原始定义位置
    Origin origin;

    PTR<AnnotationArgument> getArgument() const;
    PTR<AnnotationArgument> getArgument(const PTR<Name>& name) const;
    ConstValue getConstValue(const PTR<Name>& name) const;
    String getString(const PTR<Name>& name) const;
    Int32 getInteger(const PTR<Name>& name) const;
    bool getBoolean(const PTR<Name>& name) const;
    PTR<ClassType> getType(const PTR<Name>& name) const;
    PTR<Symbol> getMember(const PTR<Name>& name) const;
    PTR<ConstPropertyList> getProperties(const PTR<Name>& name) const;

    const bool hasArgument(const PTR<Name>& name) const;
    void putArgument(const PTR<Name>& name, const PTR<AnnotationArgument>& argument);
    const bool empty() const;
  };

  /// 注解处理器处理返回结果
  enum struct ProcessResult {
    /// 没有做出什么修改，编译器无需重新分析任何东西
    ModifiedNone = 0,
    /// 修改了当前注解的语法树，返回该结果，编译器将重新对当前语法树进行符号填充和语法树标注
    ModifiedCurrentTree,
    /// 修改了当前所处类，返回该结果，编译器将重新对当前整个类重新进行符号填充和语法树标注
    ModifiedCurrentClass,
    /// 修改了所有语法树，需要编译器对整个编译环境中所有语法树重新进行符号填充和语法树标注
    ModifiedAll,
  };

  /// 注解处理器
  class AnnotationProcessor {
  public:
    explicit AnnotationProcessor(const PTR<Context>& context);

    /// 注解的处理阶段
    virtual TaskKind getTaskKind() = 0;

    /// 获取注解处理器支持的成员级别
    virtual Modifiers getLevelModifiers() = 0;

    /// 获取注解参数
    virtual List<PTR<AnnotationParameter>>& getParameters() = 0;

    /// 处理被注解的语法树
    /// @param tree 被注解的语法树
    /// @param arguments 注解的调用参数
    /// @param context 编译器上下文
    /// @return 返回处理结果，具体可参见 {@struct ProcessResult}
    virtual ProcessResult processTree(const PTR<AnnotatedTree>& tree,
      const PTR<AnnotationArgumentMap>& arguments, const PTR<Context>& context) = 0;

    /// 查找注解处理器指定名称的参数
    /// @param name 参数名称
    PTR<AnnotationParameter> findParameter(const PTR<Name>& name);
  };

  /// 值输出规则处理时环境
  struct ValueOutputParams {
    PTR<Source> source;
    PTR<Context> context;
    PTR<Name> var_name;
  };
  /// 值输出规则
  class ValueOutputRule {
  public:
    /// 根据常量赋值执行输出逻辑（比如将路径文件处理输出到编译输出目录）
    /// @param value 常量值
    /// @param params 值输出规则处理时的传入的环境参数
    virtual void performOutputAction(ConstValue& value, ValueOutputParams& params) = 0;

    /// 根据常量赋值生成输出时平台代码
    /// @param value 常量值
    /// @param params 值输出规则处理时的传入的环境参数
    virtual String getAsOutputCode(ConstValue& value, ValueOutputParams& params) = 0;
  };

  class AnnotationArgumentsCollector;
  /// 注解处理器容器
  class AnnotationManager : public Component {
  public:
    PTR<Name> async_method_unique_thread;

    explicit AnnotationManager(const PTR<Context>& context);

    void addAnnotation(const PTR<Name>& name, const PTR<AnnotationProcessor>& processor);

    bool hasAnnotation(const PTR<Name>& name) const;

    PTR<AnnotationProcessor> getAnnotation(const PTR<Name>& name) const;

    ProcessResult processAnnotations(const TaskKind& kind, const PTR<AnnotatedTree>& tree);

    void addRule(const PTR<Name>& name, const PTR<ValueOutputRule>& rule);

    bool hasRule(const PTR<Name>& name) const;

    PTR<ValueOutputRule> getRule(const PTR<Name>& name) const;

    template<typename Func, typename = std::enable_if_t<is_lambda_or_func<Func, void, const PTR<Name>&>>>
    void forEachAnnotationName(Func&& consumer) {
      for (const PAIR<const PTR<Name>, PTR<AnnotationProcessor>>& pair : annotation_map_) {
        std::forward<Func>(consumer)(pair.first);
      }
    }

    String getType() override;
    DECL_COMPONENT_FACTORY(AnnotationManager)
  private:
    HashMap<PTR<Name>, PTR<AnnotationProcessor>, NamePtrHash, NamePtrEqual> annotation_map_;
    HashMap<PTR<Name>, PTR<ValueOutputRule>, NamePtrHash, NamePtrEqual> value_rule_map_;
    WPTR<Context> context_;
    PTR<NameTable> name_tab_;
    Set<PTR<Name>> errored_names_;
    UPTR<AnnotationArgumentsCollector> arguments_collector_;
    void errorAt(const PTR<Tree>& tree, const char* key, ...) const;
  };

  class FindTreeBySymbol;
  /// Tree Api组件，提供Tree查询接口
  class TreeApi : public Component {
  public:
    explicit TreeApi(const PTR<Context>& context);

    /// 根据Symbol获取原始定义语法树
    /// @param symbol Symbol
    /// @return Symbol对应定义的语法树，可能为空
    PTR<Tree> getTree(const PTR<Symbol>& symbol) const;

    /// 根据Symbol获取原始定义语法树，并强转为指定类型
    /// @tparam T Tree派生类型
    /// @param symbol Symbol
    /// @return Symbol对应定义的语法树，可能为空
    template<typename T>
    PTR<T> getTreeAs(const PTR<Symbol>& symbol) const {
      return std::static_pointer_cast<T>(getTree(symbol));
    }

    /// 根据Symbol获取语法树的TreePath
    /// @param symbol Symbol
    PTR<TreePath> getTreePath(const PTR<Symbol>& symbol) const;

    /// 根据类的完整类名获取类定义语法树
    /// @param full_name 完整类名
    /// @return 对应名称的语法树，可能为空
    PTR<ClassTree> getClassByName(const PTR<Name>& full_name) const;

    /// 获取指定被注解的语法树
    /// @param anno_name 注解名称
    List<PTR<AnnotatedTree>> getAnnotatedWith(const PTR<Name>& anno_name) const;

    /// 根据平台类名获取在结绳中的指代类
    /// @param alias_name 指代类名
    PTR<ClassTree> getAliasClass(const String& alias_name) const;

    String getType() override;
    DECL_COMPONENT_FACTORY(TreeApi)
  private:
    WPTR<Context> context_;
    UPTR<FindTreeBySymbol> tree_finder_symbol_;
  };

  /// Symbol Api组件，提供Symbol查询接口
  class SymbolApi : public Component {
  public:
    explicit SymbolApi(const PTR<Context>& context);

    /// 根据完整类名获取ClassSymbol
    /// @param full_name 完整类名
    PTR<ClassSymbol> getClassSymbol(const PTR<Name>& full_name) const;

    /// 获取指定被注解的Symbol
    /// @param anno_name 注解名称
    List<PTR<Symbol>> getAnnotatedWith(const PTR<Name>& anno_name) const;

    /// 根据平台类名获取在结绳中的指代类ClassSymbol
    /// @param alias_name 指代类名
    PTR<ClassSymbol> getAliasClass(const String& alias_name) const;

    String getType() override;
    DECL_COMPONENT_FACTORY(SymbolApi)
  private:
    WPTR<Context> context_;
  };

  /// 文件搜索器，用于搜索代码中指定的相对路径文件
  class FileSearcher : public Component {
  public:
    static String kScopeSource;
    static String kScopeLib;
    static String kScopeRes;
    static String kScopeAssets;

    /// 为指定Scope增加搜索前缀路径
    /// @param scope 作用域
    /// @param path 路径
    void addSearchPrefix(const String& scope, const String& path);

    /// 搜寻外部源文件
    /// @param current_dir 当前源代码.t文件所处目录
    /// @param relative_path 要搜寻的相对路径
    File searchSource(const String& current_dir, const String& relative_path);

    /// 搜寻外部依赖库
    /// @param current_dir 当前源代码.t文件所处目录
    /// @param relative_path 要搜寻的相对路径
    File searchLib(const String& current_dir, const String& relative_path);

    /// 搜寻安卓资源
    /// @param current_dir 当前源代码.t文件所处目录
    /// @param relative_path 要搜寻的相对路径
    File searchRes(const String& current_dir, const String& relative_path);

    /// 搜寻附加资源
    /// @param current_dir 当前源代码.t文件所处目录
    /// @param relative_path 要搜寻的相对路径
    File searchAssets(const String& current_dir, const String& relative_path);

    /// 在指定作用域下搜寻文件
    /// @param scope 作用域
    /// @param current_dir 当前源代码.t文件所处目录
    /// @param relative_path 要搜寻的相对路径
    File search(const String& scope, const String& current_dir, const String& relative_path);

    String getType() override;
    DECL_COMPONENT_FACTORY(FileSearcher)
  private:
    // 每个scope的搜索路径前缀，可以有多个，搜寻不同scope的文件会把对应scope所有前缀路径都匹配一遍
    HashMap<String, List<String>> scope_prefixes_map_;

    /// 兼容结绳V4编译器的文件搜寻逻辑
    /// @param selected_path 相对路径
    /// @param curr_path 当前所处路径
    /// @return
    static String finalizePathCompatV4(const String& selected_path, const String& curr_path);
  };

  /// 安卓平台的依赖库搜寻器接口
  class AndroidLibResolver {
  public:
    /// 依赖库搜寻逻辑
    /// @param path 依赖库路径
    /// @param messages 编译器环境中的信息输出器
    virtual AndroidLibSet resolve(const String& path, const PTR<Messages>& messages) = 0;
  };

  /// 各平台的外部依赖库统一管理器，用于搜寻各平台代码中指定的依赖库(目前只适配安卓平台)
  class DependencyResolver : public Component {
  public:
    /// 注册一个安卓平台的依赖库搜寻器
    /// @param resolver AndroidLibResolver实例指针
    void addAndroidLibResolver(const PTR<AndroidLibResolver>& resolver);

    /// 搜寻安卓平台的依赖库
    /// @param path 依赖库路径
    AndroidLibSet resolveAndroidLib(const String& path, const PTR<Messages>& messages);

    String getType() override;
    DECL_COMPONENT_FACTORY(DependencyResolver)
  private:
    Set<PTR<AndroidLibResolver>> android_resolvers_;
  };

  /// 平台编译输出结果
  class TargetOutput : public Component {
  public:
    /// 安卓平台的输出结果
    AndroidOutput android;
    /// Cxx的输出结果
    CxxOutput cxx;

    String getType() override;
    DECL_COMPONENT_FACTORY(TargetOutput)
  };

  DEF_COMPONENT_NAME(Options)
  DEF_COMPONENT_NAME(NameTable)
  DEF_COMPONENT_NAME(Messages)
  DEF_COMPONENT_NAME(CompilationUnitMerger)
  DEF_COMPONENT_NAME(SourceManager)
  DEF_COMPONENT_NAME(TreeTable)
  DEF_COMPONENT_NAME(SymbolTable)
  DEF_COMPONENT_NAME(NameMangler)
  DEF_COMPONENT_NAME(AnnotationManager)
  DEF_COMPONENT_NAME(TreeApi)
  DEF_COMPONENT_NAME(SymbolApi)
  DEF_COMPONENT_NAME(FileSearcher)
  DEF_COMPONENT_NAME(DependencyResolver)
  DEF_COMPONENT_NAME(TargetOutput)
}
#endif //TIEC_COMPONENT_H
